<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />

  <!-- Use the .htaccess and remove these lines to avoid edge case issues.
       More info: h5bp.com/b/378 -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

  <title>Canvas Demo</title>
  <meta name="description" content="HTML5 Canvas demo" />
  <meta name="author" content="Roger Xu" />

  <!-- Mobile viewport optimized: h5bp.com/viewport -->
  <meta name="viewport" content="width=device-width,initial-scale=1" />

  <!-- Place favicon.ico and apple-touch-icon.png in the root directory: mathiasbynens.be/notes/touch-icons -->

  <link rel="stylesheet" href="../css/style.css" />
  <link rel="stylesheet" href="../script/libs/jquery-ui/themes/base/jquery.ui.all.css" />

  <!-- All JavaScript at the bottom, except this Modernizr build incl. Respond.js
       Respond is a polyfill for min/max-width media queries. Modernizr enables HTML5 elements & feature detects;
       for optimal performance, create your own custom Modernizr build: www.modernizr.com/download/ -->
  <script src="../script/libs/modernizr-2.0.6.min.js"></script>

  <style>
    .hidden {
        display: none;
    }

    .clearfix {
        clear: both;
    }

    nav ul {
        margin: 0;
        padding: 0;
        font-weight: bold;
    }

    canvas {
        border: 1px solid black;
    }
  </style>
</head>

<body>
  <header>
    <h1 style="float: left">Canvas Demo</h1>
    <div class="clearfix"></div>
  </header>

  <nav id="navigation">
    <ul>
      <li id="version">Unknown jQuery Version</li>
      <li id="ui-version">Unknown jQuery UI Version</li>
    </ul>
  </nav>

  <div id="main" role="main">
    <p>God helps those who help themselves.</p>
    <div id="toolbar"></div>
    <div id="content">
      <canvas id="userGraph" width="500" height="500">
        User Graph
      </canvas>
    </div>
  </div>

  <footer>
    <div>Copyright &copy; 2011. All rights reserved.</div>
  </footer>

  <!-- JavaScript at the bottom for fast page loading -->

  <script src="../script/libs/jquery-1.7.1.js"></script>
  <script>window.jQuery || document.write('<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>')</script>
  <script src="../script/libs/jquery-ui-1.8.16.js"></script>
  <script>window.jQuery.ui || document.write('<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"><\/script>')</script>
  <script src="../script/libs/json2.js"></script>
  <script src="../script/libs/jsrender.js"></script>

  <!-- scripts concatenated and minified via ant build script-->
  <script defer src="../script/plugins.js"></script>
  <!-- end scripts-->

  <script>
    function drawRect(ctx) {
        ctx.fillRect(25, 25, 100, 100);
        ctx.clearRect(45, 45, 60, 60);
        ctx.strokeRect(50, 50, 50, 50);
    }

    function drawTriangle(ctx) {
        ctx.beginPath();
        ctx.moveTo(75, 50);
        ctx.lineTo(100, 75);
        ctx.lineTo(100, 25);
        ctx.fill();
    }

    function drawSmile(ctx) {
        ctx.beginPath();
        ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Outer circle
        ctx.moveTo(110, 75);
        ctx.arc(75, 75, 35, 0, Math.PI, false); // Mouth (clockwise)
        ctx.moveTo(65, 65);
        ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // Left eye
        ctx.moveTo(95, 65);
        ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // Right eye
        ctx.stroke();
    }

    function drawHeart(ctx) {
        // Bezier curves example
        ctx.beginPath();
        ctx.moveTo(75,40);
        ctx.bezierCurveTo(75,37,70,25,50,25);
        ctx.bezierCurveTo(20,25,20,62.5,20,62.5);
        ctx.bezierCurveTo(20,80,40,102,75,120);
        ctx.bezierCurveTo(110,102,130,80,130,62.5);
        ctx.bezierCurveTo(130,62.5,130,25,100,25);
        ctx.bezierCurveTo(85,25,75,37,75,40);
        ctx.fill();
    }

    function drawTransparent(ctx) {
        ctx.fillStyle = '#FD0';
        ctx.fillRect(0, 0, 75, 75);
        ctx.fillStyle = '#6C0';
        ctx.fillRect(75, 0, 75, 75);
        ctx.fillStyle = '#09F';
        ctx.fillRect(0, 75, 75, 75);
        ctx.fillStyle = '#F30';
        ctx.fillRect(75, 75, 75, 75);
        ctx.fillStyle = '#FFF';

        // set transparency value
        ctx.globalAlpha = 0.2;

        // draw semi transparent circles
        for (var i = 0; i < 7; i++) {
            ctx.beginPath();
            ctx.arc(75, 75, 10 + 10 * i, 0, Math.PI * 2, true);
            ctx.fill();
        }
    }

    function drawGradient(ctx) {
        // create linear gradient
        var linearGradient = ctx.createLinearGradient(0, 0, 0, 150);
        linearGradient.addColorStop(0, 'blue');
        linearGradient.addColorStop(0.5, 'white');
        linearGradient.addColorStop(0.5, 'green');
        linearGradient.addColorStop(1, 'white');

        // assign gradients to fill and stroke styles
        ctx.fillStyle = linearGradient;

        // draw shapes
        ctx.fillRect(10, 10, 130, 130);

        // create radial gradient
        var radialGradient = ctx.createRadialGradient(45, 45, 10, 52, 50, 30);
        radialGradient.addColorStop(0, '#A7D30C');
        radialGradient.addColorStop(0.7, '#019F62');
        radialGradient.addColorStop(1, 'rgba(1, 159, 98, 0)');

        // assign gradients to fill and stroke styles
        ctx.fillStyle = radialGradient;

        // draw shapes
        ctx.fillRect(0, 0, 150, 150);
    }

    function drawShadow(ctx) {
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;
        ctx.shadowBlur = 2;
        ctx.shadowColor = 'rgba(0, 0, 0, 0.5)';

        ctx.font = '20px Arial';
        ctx.fillStyle = 'black';
        ctx.fillText('Hello World!', 5, 30);
    }

    function drawSaveRestore(ctx) {
        ctx.fillRect(0, 0, 150, 150); // black
        ctx.save();

        ctx.fillStyle = '#09F'; // blue
        ctx.fillRect(15, 15, 120, 120);

        ctx.save();
        ctx.fillStyle = '#FFF'; // white
        ctx.globalAlpha = 0.5;
        ctx.fillRect(30, 30, 90, 90);

        ctx.restore(); // blue
        ctx.fillRect(45, 45, 60, 60);

        ctx.restore(); // black
        ctx.fillRect(60, 60, 30, 30);
    }

    function drawSpirograph(ctx, r1, r2, o) {
        var x1 = r1 - o;
        var y1 = 0;
        var i = 1;
        ctx.beginPath();
        ctx.moveTo(x1, y1);

        do {
            if (i > 20000) {
                break;
            }

            var x2 = (r1 + r2) * Math.cos(i * Math.PI / 72) - (r2 + o) * Math.cos(((r1 + r2) / r2) * (i * Math.PI / 72));
            var y2 = (r1 + r2) * Math.sin(i * Math.PI / 72) - (r2 + o) * Math.sin(((r1 + r2) / r2) * (i * Math.PI / 72));
            ctx.lineTo(x2, y2);
            x1 = x2;
            y1 = y2;
            i++;
        } while (x2 != r1 - o && y2 != 0);

        ctx.stroke();
    }

    function drawTranslate(ctx) {
        ctx.fillRect(0, 0, 300, 300);
        for (var i = 0; i < 3; i++) {
            for (var j = 0; j < 3; j++) {
                ctx.save();
                ctx.strokeStyle = '#9CFF00';
                ctx.translate(50 + j * 100, 50 + i * 100);
                drawSpirograph(ctx, 20 * (j + 2) / (j + 1), -8 * (i + 3) / (i + 1), 10);
                ctx.restore();
            }
        }
    }

    function drawRotate(ctx) {
        ctx.translate(75, 75);

        for (var i = 1; i < 6; i++) { // loop through rings
            ctx.save();
            ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)';

            for (var j = 0; j < i * 6; j++) { // individual dots
                ctx.rotate(Math.PI * 2 / (i * 6));
                ctx.beginPath();
                ctx.arc(0, i * 12.5, 5, 0, Math.PI * 2, true);
                ctx.fill();
            }

            ctx.restore();
        }
    }

    function drawScale(ctx) {
        ctx.strokeStyle = '#FC0';
        ctx.lineWidth = 1.5;
        ctx.fillRect(0, 0, 300, 300);

        // uniform scaling
        ctx.save();
        ctx.translate(50, 50);
        drawSpirograph(ctx, 22, 6, 5); // no scaling

        ctx.translate(100, 0);
        ctx.scale(0.75, 0.75);
        drawSpirograph(ctx, 22, 6, 5);

        ctx.translate(133, 0);
        ctx.scale(0.75, 0.75);
        drawSpirograph(ctx, 22, 6, 5);
        ctx.restore();

        // non-uniform scaling (v direction)
        ctx.strokeStyle = '#0CF';
        ctx.save();
        ctx.translate(50, 150);
        ctx.scale(1, 0.75);
        drawSpirograph(ctx, 22, 6, 5);

        ctx.translate(100, 0);
        ctx.scale(1, 0.75);
        drawSpirograph(ctx, 22, 6, 5);

        ctx.translate(100, 0);
        ctx.scale(1, 0.75);
        drawSpirograph(ctx, 22, 6, 5);
        ctx.restore();

        // non-uniform scaling (x direction)
        ctx.strokeStyle = '#CF0';
        ctx.save();
        ctx.translate(50, 250);
        ctx.scale(0.75, 1);
        drawSpirograph(ctx, 22, 6, 5);

        ctx.translate(133, 0);
        ctx.scale(0.75, 1);
        drawSpirograph(ctx, 22, 6, 5);

        ctx.translate(177, 0);
        ctx.scale(0.75, 1);
        drawSpirograph(ctx, 22, 6, 5);
        ctx.restore();
    }

    function drawTransform(ctx) {
        var sin = Math.sin(Math.PI / 6);
        var cos = Math.cos(Math.PI / 6);
        ctx.translate(200, 200);

        var c = 0;
        for (var i = 0; i <= 12; i++) {
            c = Math.floor(255 / 12 * i);
            ctx.fillStyle = 'rgb(' + c + ',' + c + ',' + c +')';
            ctx.fillRect(0, 0, 100, 10);
            ctx.transform(cos, sin, -sin, cos, 0, 0);
        }

        ctx.setTransform(-1, 0, 0, 1, 200, 200);
        ctx.fillStyle = 'rgba(255, 128, 255, 0.5)';
        ctx.fillRect(0, 50, 100, 100);
    }

    function drawStar(ctx, r) {
        ctx.save();
        ctx.beginPath();
        ctx.moveTo(r, 0);

        for (var i = 0; i < 9; i++) {
            ctx.rotate(Math.PI / 5);
            if (i % 2 === 0) {
                ctx.lineTo((r / 0.525731) * 0.200811, 0);
            } else {
                ctx.lineTo(r, 0);
            }
        }

        ctx.closePath();
        ctx.fill();
        ctx.restore();
    }

    function drawClip(ctx) {
        ctx.fillRect(0, 0, 150, 150);
        ctx.translate(75, 75);

        ctx.beginPath();
        ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
        ctx.clip();

        // draw background
        var lingrad = ctx.createLinearGradient(0, -75, 0, 75);
        lingrad.addColorStop(0, '#232256');
        lingrad.addColorStop(1, '#143778');

        ctx.fillStyle = lingrad;
        ctx.fillRect(-75, -75, 150, 150);

        // draw stars
        for (var i = 1; i < 50; i++) {
            ctx.save();
            ctx.fillStyle = '#FFF';
            ctx.translate(75 - Math.floor(Math.random() * 150), 75 - Math.floor(Math.random() * 150));
            drawStar(ctx, Math.floor(Math.random() * 4) + 2);
            ctx.restore();
        }
    }

    function drawAnimation(ctx) {
        var _drawSingleFrame = function() {
            ctx.globalCompositeOperation = 'destination-over';
            ctx.clearRect(0, 0, 300, 300); // clear canvas

            ctx.fillStyle = 'rgba(0, 0, 0, 0.4)';
            ctx.strokeStyle = 'rgba(0, 153, 255, 0.4)';
            ctx.save();
            ctx.translate(150, 150);

            var time = new Date();
            ctx.rotate(2 * Math.PI / 60 * time.getSeconds() + 2 * Math.PI / 60000 * time.getMilliseconds());
            ctx.translate(105, 0);
            ctx.beginPath();
            ctx.arc(0, 0, 20, 0, Math.PI * 2, false); // earth
            ctx.fill();

            ctx.restore();

            ctx.beginPath();
            ctx.arc(150, 150, 105, 0, Math.PI * 2, false); // earth orbit
            ctx.stroke();

            // sun
            ctx.beginPath();
            ctx.arc(150, 150, 40, 0, Math.PI * 2, false); // earth orbit
            ctx.fill();
        };

        setInterval(_drawSingleFrame, 100);
    }

    function drawLoopImage(ctx) {
        var img = new Image();

        // image
        img.src = 'http://upload.wikimedia.org/wikipedia/commons/thumb/8/83/Capitan_Meadows%2C_Yosemite_National_Park.jpg/800px-Capitan_Meadows%2C_Yosemite_National_Park.jpg';


        img.onload = function() {
            var canvasXSize = 800;
            var canvasYSize = 200;
            var scale = 1.05;
            var x = 0;
            var y = -4.5; // vertical offset
            var dx = 0.75;
            var imgW = img.width * scale;
            var imgH = img.height * scale;

            var clearX = imgW;
            var clearY = imgH;

            var _drawSingleFrame = function() {
                ctx.clearRect(0, 0, clearX, clearY); // clear

                if (imgW <= canvasXSize) {
                    // reset
                    if (x > canvasXSize) {
                        x = 0;
                    }

                    if (x > canvasXSize - imgW) {
                        ctx.drawImage(img, x - canvasXSize + 1, y, imgW, imgH);
                    }
                } else {
                    if (x > canvasXSize) {
                        x = canvasXSize - imgW;
                    }

                    if (x > canvasXSize - imgW) {
                        ctx.drawImage(img, x - imgW + 1, y, imgW, imgH);
                    }
                }

                ctx.drawImage(img, x, y, imgW, imgH);

                x += dx;
            };

            // loop
            var speed = 30;
            setInterval(_drawSingleFrame, speed);
        };
    }
  </script>
  <script>
    $(document).ready(function() {
        // version
        var version = $.fn.jquery;
        $('#version').html('jQuery: ' + version);
        var uiVersion = $.ui.version;
        $('#ui-version').html('jQuery UI: ' + uiVersion);

        // canvas
        var canvas = $('#userGraph').get(0);
        var ctx = canvas.getContext('2d');

        // rectangle
        //drawRect(ctx);

        // triangle
        //drawTriangle(ctx);

        // smile
        //drawSmile(ctx);

        // heart
        //drawHeart(ctx);

        // transparent
        //drawTransparent(ctx);

        // gradient
        //drawGradient(ctx);

        // shadow
        //drawShadow(ctx);

        // save & restore
        //drawSaveRestore(ctx);

        // translate
        //drawTranslate(ctx);

        // rotate
        //drawRotate(ctx);

        // scale
        //drawScale(ctx);

        // transform
        //drawTransform(ctx);

        // clip
        //drawClip(ctx);

        // animation
        //drawAnimation(ctx);

        // loop
        drawLoopImage(ctx);
    });
  </script>
</body>
</html>